package request

import (
	"blog/core/response"
	"blog/core/validate"
	"encoding/json"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/spf13/cast"
)

type request struct {
	c          *gin.Context
	postParams map[string]interface{}
}

// Request , 获得json参数有问题
func Request(c *gin.Context) InterfaceRequest {
	var PostParams map[string]interface{} = map[string]interface{}{}
	switch c.GetHeader("Content-Type") {
	case binding.MIMEPOSTForm:
		c.Request.ParseForm()
		for k, v := range c.Request.Form {
			if len(v) > 1 {
				PostParams[k] = v
			} else {
				PostParams[k] = v[0]
			}
		}
	case binding.MIMEMultipartPOSTForm:
		c.Request.ParseForm()
		c.Request.ParseMultipartForm(32 << 20)
		for k, v := range c.Request.Form {
			if len(v) > 1 {
				PostParams[k] = v
			} else {
				PostParams[k] = v[0]
			}
		}
	case binding.MIMEJSON:
		decoder := json.NewDecoder(c.Request.Body)
		decoder.Decode(&PostParams)
	}

	return &request{
		c:          c,
		postParams: PostParams,
	}
}

func (r *request) GetContext() *gin.Context {
	return r.c
}

// Get 获得参数
func (r *request) Get(key string) string {
	return r.c.Query(key)
}

func (r *request) GetInt(key string) int {
	return cast.ToInt(r.Get(key))
}

func (r *request) GetIntDefault(key string, val int) int {
	v := r.Get(key)
	if vv := cast.ToInt(v); vv != 0 {
		return vv
	}

	return val
}

// func(r *request) Param()

func (r *request) DefaultPostFormInt(key string, value interface{}) int {
	var str string
	switch vv := value.(type) {
	case int:
		str = strconv.Itoa(vv)
	case string:
		str = vv
	}
	v := r.c.DefaultPostForm(key, str)
	vi, _ := strconv.Atoi(v)
	return int(vi)
}

func (r *request) DefaultPostFormInt64(key string, value interface{}) int64 {
	return int64(r.DefaultPostFormInt(key, value))
}

func (r *request) ParamString(key string) string {
	return cast.ToString(r.c.Param(key))
}

func (r *request) ParamIntDefault(key string, value int) int {
	if k := r.ParamInt(key); k != 0 {
		return k
	}

	return value
}

func (r *request) post(key string) interface{} {
	return r.postParams[key]
}

func (r *request) PostString(key string) string {
	return cast.ToString(r.c.PostForm(key))
}

func (r *request) PostStringDefault(key string, val string) string {
	v := r.PostString(key)
	if v == "" {
		return val
	}

	return v
}

func (r *request) PostInt(key string) int {
	return cast.ToInt(r.post(key))
}

func (r *request) PostIntDefault(key string, defaultVal int) int {
	val := r.post(key)
	i := cast.ToInt(val)
	if defaultVal != 0 && i == 0 {
		return defaultVal
	}

	return i
}

func (r *request) Response() *response.Data {
	return response.Response(r.c)
}

func (r *request) Validate() validate.Validate {
	return validate.New()
}

func (r *request) InputStr(key string) string {
	return cast.ToString(r.postParams[key])
}

func (r *request) InputInt(key string) int {
	return cast.ToInt(r.postParams[key])
}

func (r *request) InputIntDefault(key string, df int) int {
	num := cast.ToInt(r.postParams[key])
	if num != 0 {
		return num
	} else {
		return df
	}
}

func (r *request) InputStringDefault(key, df string) string {
	str := cast.ToString(r.postParams[key])
	if str == "" {
		return df
	}

	return str
}

func (r *request) ParamInt(key string) int {
	return cast.ToInt(r.c.Param(key))
}
